package fem2.material;

import java.util.ArrayList;

import fem2.Element;
import fem2.MaterialModel;
import fem2.Model;

public class TopOptDensityFilter extends TopOptFilter {

	private Model m;
	private double rmin;

	public TopOptDensityFilter(Model m, double rmin) {
		this.m = m;
		this.rmin = rmin;
	}

	@Override
	public void initialize() {
		this.computeDistance(m, rmin);
	}

	@Override
	public double filterComplianceSensitivity(Element e, MaterialModel mm) {
		ArrayList<Element> elemList = mapElemId.get(e);
		ArrayList<Double> elemWeights = mapElemWeight.get(e);
		TopOptMaterialModel tomm = (TopOptMaterialModel) mm;
		double nom = 0.0;
		double denom = 0.0;
		for (int i = 0; i < elemList.size(); i++) {
			Element e1 = elemList.get(i);
			double dce1 = tomm.getComplianceSensitivity(e1);
			nom += elemWeights.get(i) * dce1;
			denom += elemWeights.get(i);
		}
		return nom / denom;
	}

	@Override
	public double filterVolumeSensitivity(Element e, MaterialModel mm) {
		ArrayList<Element> elemList = mapElemId.get(e);
		ArrayList<Double> elemWeights = mapElemWeight.get(e);
		TopOptMaterialModel tomm = (TopOptMaterialModel) mm;
		double nom = 0.0;
		double denom = 0.0;
		for (int i = 0; i < elemList.size(); i++) {
			Element e1 = elemList.get(i);
			double dve1 = tomm.getVolumeSensitivity(e1);
			nom += elemWeights.get(i) * dve1;
			denom += elemWeights.get(i);
		}
		return nom / denom;
	}

	@Override
	public double filterDensity(Element e, MaterialModel mm) {
		ArrayList<Element> elemList = mapElemId.get(e);
		ArrayList<Double> elemWeights = mapElemWeight.get(e);
		TopOptMaterialModel tomm = (TopOptMaterialModel) mm;
		double nom = 0.0;
		double denom = 0.0;
		for (int i = 0; i < elemList.size(); i++) {
			Element e1 = elemList.get(i);
			double xe1 = tomm.getDensity(e1).getValue();
			nom += elemWeights.get(i) * xe1;
			denom += elemWeights.get(i);
		}
		return nom / denom;
	}

}
